package com.unlcn.ils.wms.backend.service.inbound.impl;

import cn.huiyunche.commons.exception.BusinessException;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.unlcn.ils.wms.backend.enums.*;
import com.unlcn.ils.wms.backend.service.inbound.WmsInterfaceForTmsService;
import com.unlcn.ils.wms.backend.util.DateUtils;
import com.unlcn.ils.wms.backend.util.SnowflakeIdWorker;
import com.unlcn.ils.wms.base.dto.WmsForTmsInterfaceDTO;
import com.unlcn.ils.wms.base.dto.WmsForTmsUpdateInboundOrderDTO;
import com.unlcn.ils.wms.base.mapper.extmapper.WmsInboundOrderExtMapper;
import com.unlcn.ils.wms.base.mapper.extmapper.WmsWarehouseNoticeExtMapper;
import com.unlcn.ils.wms.base.mapper.inbound.WmsTmsLogMapper;
import com.unlcn.ils.wms.base.mapper.inbound.WmsTmsOrderMapper;
import com.unlcn.ils.wms.base.model.inbound.WmsTmsLogWithBLOBs;
import com.unlcn.ils.wms.base.model.inbound.WmsTmsOrder;
import com.unlcn.ils.wms.base.model.inbound.WmsWarehouseNoticeDetail;
import com.unlcn.ils.wms.base.model.inbound.WmsWarehouseNoticeHead;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * wms对接tms的接口业务处理
 */
@Service
public class WmsInterfaceForTmsServiceImpl implements WmsInterfaceForTmsService {

    private final Logger LOGGER = LoggerFactory.getLogger(WmsInterfaceForTmsServiceImpl.class);

    @Value("${tms.encode.key}")
    private String ENCODE_KEY;

    private WmsInboundOrderExtMapper wmsInboundOrderExtMapper;
    private WmsTmsLogMapper WmsTmsLogMapper;
    private WmsTmsOrderMapper wmsTmsOrderMapper;
    @Autowired
    private WmsWarehouseNoticeExtMapper wmsWarehouseNoticeExtMapper;

    @Autowired
    public void setWmsInboundOrderExtMapper(WmsInboundOrderExtMapper wmsInboundOrderExtMapper) {
        this.wmsInboundOrderExtMapper = wmsInboundOrderExtMapper;
    }

    @Autowired
    public void setWmsTmsLogMapper(com.unlcn.ils.wms.base.mapper.inbound.WmsTmsLogMapper wmsTmsLogMapper) {
        WmsTmsLogMapper = wmsTmsLogMapper;
    }

    @Autowired
    public void setWmsTmsOrderMapper(WmsTmsOrderMapper wmsTmsOrderMapper) {
        this.wmsTmsOrderMapper = wmsTmsOrderMapper;
    }

    /**
     * 更新订单信息
     * <p>
     * 2018-1-31 新功能:新增入库验车模糊查询,先定时抓取数据(此接口用于定时任务抓取的数据后进行更新)
     * 可能多个订单更新,可能增车/减车/换车 每次都插入接口表数据,并以订单号最新的为准
     * 系统订单号 不会改变
     * 2018-4-19 因入库通知单重构-此方法过时,新方法{@link WmsInterfaceForTmsServiceImpl#updateInboundOrder}
     * </p>
     */
    @Deprecated
    @Override
    public ArrayList<Map<String, String>> updateInboundOrderOld(WmsForTmsInterfaceDTO interfaceDTO) {
        LOGGER.info("WmsInterfaceForTmsServiceImpl.updateInboundOrderOld param:{}", interfaceDTO);
        //记录接口数据日志
        Date date = new Date();
        if (Objects.equals(interfaceDTO, null))
            throw new BusinessException("参数不能为空!");
        String orderDto = interfaceDTO.getUpdateOrderDto();
        String key = interfaceDTO.gethKey();

        Runnable runnable = () -> {
            try {
                WmsTmsLogWithBLOBs log = new WmsTmsLogWithBLOBs();
                log.setBody(orderDto);
                log.setHead("tms modify order");
                log.setGmtCreate(date);
                log.setGmtUpdate(date);
                log.setSendType(WmsGateControllerTypeEnum.GATE_IN.getCode());
                log.setUrl("tms.updateInboundOrder");
                WmsTmsLogMapper.insertSelective(log);
            } catch (Exception e) {
                LOGGER.error("修改order接口数据失败 error:", e);
                e.printStackTrace();
            }
            LOGGER.info("修改order接口数据保存成功");
        };
        new Thread(runnable).start();

        List<WmsForTmsUpdateInboundOrderDTO> dto = JSONObject.parseArray(orderDto, WmsForTmsUpdateInboundOrderDTO.class);
        if (StringUtils.isBlank(key))
            throw new BusinessException("接口请求key不能为空!");
        if (!ENCODE_KEY.equals(key))
            throw new BusinessException("请输入正确的key");
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("whCode", WhCodeEnum.UNLCN_XN_CQ.getValue());
        paramMap.put("notDel", DeleteFlagEnum.NORMAL.getValue());
        ArrayList<String> newVinList = Lists.newArrayList();
        dto.stream().filter(v -> (!Objects.equals(v, null)
                && StringUtils.isNotBlank(v.getDest())))
                .forEach(td -> {
                    newVinList.add(td.getVin());
                });
        List<Map<String, Object>> data = wmsInboundOrderExtMapper.selectOrderStatusByVinList(paramMap, newVinList);
        ArrayList<String> cantInsertVins = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(data)) {
            data.stream().filter(v1 -> (!Objects.equals(v1, null) && !(Objects.equals(v1.get("od_status"), null))))
                    .forEach(v2 -> {
                        if (String.valueOf(WmsInboundStatusEnum.WMS_INBOUND_FINISH.getValue()).equals((String) v2.get("od_status"))
                                || String.valueOf(WmsInboundStatusEnum.WMS_INBOUND_WAIT_INBOUND.getValue()).equals((String) v2.get("od_status"))) {
                            cantInsertVins.add((String) v2.get("odd_vin"));
                        }
                    });
        }
        String timeStamp = DateUtils.getStringFromDate(date, DateUtils.FORMAT_DATETIME_NO_SEPARATOR);

        ArrayList<Map<String, String>> result = Lists.newArrayList();
        //新增这些修改数据--定时任务执行的时候需要进行判断订单号数据是否存在(如果存在以更新的为准)
        dto.stream().filter(v -> (!Objects.equals(v, null)
                && StringUtils.isNotBlank(v.getDest())))
                .forEach(td -> {
                    if (cantInsertVins.contains(td.getVin())) {
                        //已收货或者已入库不能进行更新
                        Map<String, String> resultMap = Maps.newHashMap();
                        resultMap.put("vin", td.getVin());
                        resultMap.put("msg", "该车架号:" + td.getVin() + "已经收货/入库,不支持更新;");
                        result.add(resultMap);
                    } else {
                        //可能是删除的车辆信息
                        WmsTmsOrder tmsOrder = new WmsTmsOrder();
                        tmsOrder.setCreateName(WmsSysSourceEnum.REST.getValue());
                        tmsOrder.setModifyName(WmsSysSourceEnum.REST.getValue());
                        tmsOrder.setFactoryWhno(td.getFactory_whno());
                        tmsOrder.setFetchTimestamp(Long.valueOf(timeStamp));
                        tmsOrder.setGmtCreate(date);
                        tmsOrder.setGmtUpdate(date);
                        tmsOrder.setIsDeleted(DeleteFlagEnum.NORMAL.getValue());
                        tmsOrder.setOdCustomerOrderNo(td.getCustOrderno());
                        tmsOrder.setOdCustomerName(td.getCustomer());
                        tmsOrder.setOdDest(td.getDest());
                        tmsOrder.setOddVehicleSpecName(td.getStyle());
                        tmsOrder.setOddVehicleSpecDesc(td.getStyleDesc());
                        tmsOrder.setOdOrigin(td.getOrigin());
                        tmsOrder.setOdStyleId(Long.valueOf(td.getStyleId()));
                        tmsOrder.setOddVin(td.getVin());
                        tmsOrder.setOddStockTransfer(td.getStocktransfer());
                        tmsOrder.setOdWaybillNo(td.getCustShipno());
                        tmsOrder.setOdOrderno(td.getOrderno());
                        tmsOrder.setOdWhCode(WhCodeEnum.UNLCN_XN_CQ.getValue());
                        tmsOrder.setOdWhName(WhCodeEnum.UNLCN_XN_CQ.getText());
                        tmsOrder.setSendBusinessFlag((byte) SendBusinessFlagEnum.SEND_N.getValue());
                        if (StringUtils.isNotBlank(td.getOd_status())) {
                            tmsOrder.setOdStatus(td.getOd_status());
                        }
                        wmsTmsOrderMapper.insertSelective(tmsOrder);
                        //已收货或者已入库不能进行更新
                        Map<String, String> resultMap = Maps.newHashMap();
                        resultMap.put("vin", td.getVin());
                        resultMap.put("msg", "更新成功!");
                        result.add(resultMap);
                    }
                });
        return result;
    }


    /**
     * 更新订单信息
     * <p>
     * 2018-1-31 新功能:新增入库验车模糊查询,先定时抓取数据(此接口用于定时任务抓取的数据后进行更新)
     * 可能多个订单更新,可能增车/减车/换车 每次都插入接口表数据,并以订单号最新的为准
     * 内部订单号 不会改变
     * 2018-4-19 因入库通知单重构-此方法新方法
     * </p>
     */
    @Deprecated
    @Override
    public ArrayList<Map<String, String>> updateInboundOrder(WmsForTmsInterfaceDTO interfaceDTO) {
        LOGGER.info("WmsInterfaceForTmsServiceImpl.updateInboundOrder param:{}", interfaceDTO);
        //记录接口数据日志
        Date date = new Date();
        if (Objects.equals(interfaceDTO, null))
            throw new BusinessException("参数不能为空!");
        String orderDto = interfaceDTO.getUpdateOrderDto();
        String key = interfaceDTO.gethKey();
        Runnable runnable = () -> {
            try {
                WmsTmsLogWithBLOBs log = new WmsTmsLogWithBLOBs();
                log.setBody(orderDto);
                log.setHead("tms-modify-order");
                log.setGmtUpdate(date);
                log.setGmtCreate(date);
                log.setSendType(WmsGateControllerTypeEnum.GATE_IN.getCode());
                log.setUrl("tms.updateInboundOrder");
                WmsTmsLogMapper.insertSelective(log);
            } catch (Exception e) {
                LOGGER.error("修改order接口数据失败 error:", e);
                e.printStackTrace();
            }
            LOGGER.info("修改order接口数据保存成功");
        };
        new Thread(runnable).start();

        List<WmsForTmsUpdateInboundOrderDTO> dto = JSONObject.parseArray(orderDto, WmsForTmsUpdateInboundOrderDTO.class);
        if (StringUtils.isBlank(key))
            throw new BusinessException("接口请求key不能为空!");
        if (!ENCODE_KEY.equals(key))
            throw new BusinessException("请输入正确的key");
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("whCode", WhCodeEnum.UNLCN_XN_CQ.getValue());
        paramMap.put("notDel", DeleteFlagEnum.NORMAL.getValue());
        ArrayList<String> newVinList = Lists.newArrayList();
        dto.stream().filter(v -> (!Objects.equals(v, null)
                && StringUtils.isNotBlank(v.getDest())))
                .forEach(td -> {
                    newVinList.add(td.getVin());
                });
        List<Map<String, Object>> data = wmsInboundOrderExtMapper.selectOrderStatusByVinList(paramMap, newVinList);
        ArrayList<String> cantInsertVins = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(data)) {
            data.stream().filter(v1 -> (!Objects.equals(v1, null) && !(Objects.equals(v1.get("od_status"), null))))
                    .forEach(v2 -> {
                        if (String.valueOf(WmsInboundStatusEnum.WMS_INBOUND_FINISH.getValue()).equals((String) v2.get("od_status"))
                                || String.valueOf(WmsInboundStatusEnum.WMS_INBOUND_WAIT_INBOUND.getValue()).equals((String) v2.get("od_status"))) {
                            cantInsertVins.add((String) v2.get("odd_vin"));
                        }
                    });
        }
        String timeStamp = DateUtils.getStringFromDate(date, DateUtils.FORMAT_DATETIME_NO_SEPARATOR);
        ArrayList<Map<String, String>> result = Lists.newArrayList();
        ArrayList<WmsWarehouseNoticeHead> heads = Lists.newArrayList();
        ArrayList<WmsWarehouseNoticeDetail> details = Lists.newArrayList();
        //新增这些修改数据 存储非已入库的数据,并在进行处理的时候修改wnd表的data_status判断是正常修改还是删除
        SnowflakeIdWorker idWorker = new SnowflakeIdWorker(31L, 31L);
        dto.stream().filter(v -> (!Objects.equals(v, null)
                && StringUtils.isNotBlank(v.getDest())))
                .forEach(td -> {
                    if (cantInsertVins.contains(td.getVin())) {
                        //已收货或者已入库不能进行更新
                        Map<String, String> resultMap = Maps.newHashMap();
                        resultMap.put("vin", td.getVin());
                        resultMap.put("msg", "该车架号:" + td.getVin() + "已经收货/入库,不支持更新;");
                        result.add(resultMap);
                    } else {
                        //可能是删除的车辆信息
                        WmsWarehouseNoticeHead head = new WmsWarehouseNoticeHead();
                        WmsWarehouseNoticeDetail detail = new WmsWarehouseNoticeDetail();
                        //设置头表的head ID
                        long headId = idWorker.nextId();
                        head.setWnhId(headId);
                        head.setWnhCustomerCode(WmsCustomerEnum.CQ_JL.getCode());
                        head.setWnhCustomerName(td.getCustomer());
                        head.setWnhCustomerOrderNo(td.getCustOrderno());
                        head.setWnhCustomerWaybillNo(td.getCustShipno());
                        head.setWnhUnlcnOrderNo(td.getOrderno());
                        head.setWnhOriginName(td.getOrigin());
                        head.setWnhDestinationName(td.getDest());
                        head.setWnhInboundNum(1);
                        head.setWnhCreate(date);
                        head.setWnhUpdate(date);
                        head.setWnhCreateUserName(WmsSysSourceEnum.REST.getValue());
                        head.setWnhUpdateUserName(WmsSysSourceEnum.REST.getValue());
                        head.setWnhDataTimestamp(Long.valueOf(timeStamp));
                        head.setWnhSysSource(WmsSysSourceEnum.REST.getValue());
                        head.setWnhBusinessStatus(WmsBusinessStatusEnum.WNH_NOT_INBOUND.getCode());
                        head.setWnhDataStatus(String.valueOf(DeleteFlagEnum.NORMAL.getValue()));
                        head.setWnhWarehouseCode(WhCodeEnum.UNLCN_XN_CQ.getValue());
                        //details
                        detail.setWndHeadId(head.getWnhId());
                        detail.setWndVin(td.getVin());
                        detail.setWndVehicleId(Long.valueOf(td.getStyleId()));
                        detail.setWndVehicleName(td.getStyle());
                        detail.setWndVehicleDesc(td.getStyleDesc());
                        detail.setWndCustomerWhno(td.getFactory_whno());
                        detail.setWndCreate(date);
                        detail.setWndUpdate(date);
                        detail.setWndCreateUserName(WmsSysSourceEnum.REST.getValue());
                        detail.setWndUpdateUserName(WmsSysSourceEnum.REST.getValue());
                        detail.setWndBusinessStatus(WmsBusinessStatusEnum.WND_NOT_RECEIVE.getCode());
                        detail.setWndSendBusinessFlag(String.valueOf(SendBusinessFlagEnum.SEND_N.getValue()));
                        detail.setWndDataStatus(String.valueOf(DeleteFlagEnum.NORMAL.getValue()));
                        detail.setWndWarehouseCode(WhCodeEnum.UNLCN_XN_CQ.getValue());
                        detail.setWndModifyType(td.getOd_status());
                        detail.setWndBusinessType(InboundOrderBusinessTypeEnum.Z1.getCode());
                        if (WmsInboundOrderStockTransferEnum.STOCK_NORMAL.getCode().equals(td.getStocktransfer())) {
                            detail.setWndTransferFlag(WmsInboundOrderStockTransferEnum.STOCK_NORMAL.getCode());
                        } else {
                            detail.setWndTransferFlag(WmsInboundOrderStockTransferEnum.STOCK_NOTCQ.getCode());
                        }
                        details.add(detail);
                        heads.add(head);
                        //已收货或者已入库不能进行更新
                        Map<String, String> resultMap = Maps.newHashMap();
                        resultMap.put("vin", td.getVin());
                        resultMap.put("msg", "更新成功!");
                        result.add(resultMap);
                    }
                });
        wmsWarehouseNoticeExtMapper.insertHeadBatch(heads);
        wmsWarehouseNoticeExtMapper.insertDetailBatch(details);

        return result;
    }

}
